﻿using System;
using System.Collections.Generic;
using System.Linq;
using Plugin.Core;
using Plugin.Configs;
using System.IO;
using System.Reflection;

namespace Plugin.Engine
{
    static class Program
    {
        /// <summary>
        /// This function can be used for load any type
        /// in a path(Directory)
        /// </summary>
        /// <typeparam name="T" example="IPlugin">Type</typeparam>
        /// <param name="directory">a directory that its contain plug-ins</param>
        /// <returns>List of loaded types</returns>
        static List<T> LoadPlugin<T>(string directory)
        {
            Type interfaceType = typeof(T);
            List<T> implementations = new List<T>();
            if (!Directory.Exists(directory)) return implementations; 
            
            foreach (var file in Directory.GetFiles(directory))
            {
                try
                {
                    foreach (var type in Assembly.LoadFile(file).GetTypes())
                    {
                        if (interfaceType.IsAssignableFrom(type) && interfaceType != type)
                        {
                            T instance = (T)Activator.CreateInstance(type);
                            implementations.Add(instance);
                        }
                    }
                }
                catch { }
            }
            return implementations;
        }

        static void Main()
        {
            string rootPath = Path.GetFullPath("Plugins");
            IHost MainHost = new Host();
            MainHost.Plugins.AddRange(LoadPlugin<IPlugin>(rootPath));
            MainHost.Run(rootPath, DateTime.Now);
        }
    }
}
